// state/StateMachine.cpp
#include <renderer/Interfaces.hpp>
#include "State.h"
#include "StateMachine.h"

using namespace STATE;

void StateMachine::SetupStateMachine(State ** ppStates, int iNumStates, int iInitialState)
{
	AssertPtr(ppStates);
	Assert(iNumStates > 0);
	AssertV(m_pStates.GetSize() == 0 && m_pCurrentState == 0,
		"This state machine already appears to be initialized" );

	m_pStates.SetArray( ppStates, iNumStates );

	if (iInitialState != STATE_ID_INVALID)
	{
		m_CurrentState = iInitialState;
		m_pCurrentState = m_pStates[iInitialState];
		m_pCurrentState->Enter();
	}
	else
	{
		m_CurrentState = STATE_ID_INVALID;
		m_pCurrentState = 0;
	}

	m_NextState = 0; // Initialize to the first state in the list.
}

void StateMachine::Update( CORE::Time & TimeDelta )
{
	if (m_NextState != STATE_ID_INVALID)
	{
		if (m_pCurrentState)
		{
			m_pCurrentState->Leave();
		}

		m_pCurrentState = m_pStates[m_NextState];

		m_pCurrentState->Enter();
		m_NextState = STATE_ID_INVALID;
	}

	m_NextState = m_pCurrentState->Update( TimeDelta );

	if (m_NextState == STATE_ID_NONE)
	{
		m_pCurrentState->Leave();
		m_pCurrentState = 0;
		m_CurrentState = STATE_ID_INVALID;
		m_NextState = STATE_ID_INVALID;
	}
}

void StateMachine::Render( IRenderingEngine * pRenderer )
{
	AssertPtr(pRenderer);

	if (!pRenderer)
		return;

	if (m_pCurrentState)
		m_pCurrentState->Render( pRenderer );
}